// 卡片的仓库 [含加密解密方法]
import getRandom from "@/utils/getRandom";
import distinct from "@/utils/distinct";
import levelData from "./levelData";

export default {
  namespaced: true, // 开启命名空间
  state: {
    // 是否显示剩余卡片数 ['文本'] [右上角] <false>
    isShowCurCard: false,
    // 下次点击是否可直接修改卡片 ['铅笔'] <false>
    isEdit: false,
    // 要修改的卡片的对象在gameCards中的索引 以及卡片信息 {i, cardId: card.cardId}
    editCard: -1,
    // 下次点击的时候是否消除点击的卡片 ['购物袋'] <false>
    isDelete: false,
    // 下次点击时是否考虑遮挡 ['放大镜'] <true>
    isCover: true,
    // 下次点击时是否消除卡槽中点击的卡片 ['下载'] <false>
    isSlotDelete: false,
    // 下次点击时是否增加卡槽中点击的卡片 ['照相机'] <false>
    isSlotAdd: false,
    // 下次点击时是否消除点击区域的所有卡片 ['剪刀'] <false>
    isDeleteArea: false,
    // 是否跳过关卡模式前4关中的一关 ['消息'] <true>
    isPass: true,
    // 当前关卡时间数据是否有效 [是否使用'消息'卡片] <true>
    isCanRanking: true,
    // 关卡进度 <1>
    levelNum: 1,
    // 当前关卡的时间和计时器id <0>
    levelTime: 0,
    // 计时器id
    levelTimerId: "",
    // 是否显示命令窗口 <false>
    isShowCmd: false,
    // 卡片数据
    cardData: {
      // [icon类名, 图标色, 背景色]
      // 0 铅笔
      0: {
        iconId: 0,
        className: "el-icon-edit",
        color: "#000",
        bg: "#f3ffeb",
        content: "经历的多了也就变得圆滑了",
        useNum: 3, // 卡片每局的可使用次数
        defaUseNum: 3, // 卡片每局的可使用次数
        effect: "将当前点击的卡片修改为下次点击的卡片",
      },
      // 1 垃圾箱
      1: {
        iconId: 1,
        className: "el-icon-delete",
        color: "#000",
        bg: "#fff4ed",
        content: "在不经意间丢弃了重要的事物",
        useNum: 3,
        defaUseNum: 3,
        effect: "随机消除5张卡片",
      },
      // 2 电话
      2: {
        iconId: 2,
        className: "el-icon-phone-outline",
        color: "#000",
        bg: "#fffcec",
        content: "“有事记得给我打电话呀”...那是手机..不是我",
        useNum: 3,
        defaUseNum: 3,
        effect: "随机消除'卡片消除数'张相同类型的卡片",
        // effect: "随机消除底层的3张卡片",
      },
      // 3 购物袋
      3: {
        iconId: 3,
        className: "el-icon-goods",
        color: "#000",
        bg: "#fbffec",
        content: "总有一天我会把里面塞得满满当当！",
        useNum: 3,
        defaUseNum: 3,
        effect: "消除一张点击的卡片",
      },
      // 4 感叹号
      4: {
        iconId: 4,
        className: "el-icon-warning-outline",
        color: "#000",
        bg: "#ffefef",
        content: "编织了千言万语, 也害怕突然的红色感叹号",
        useNum: 1,
        defaUseNum: 1,
        effect: "将顶层所有卡片变为'感叹号'",
      },
      // 5 放大镜
      5: {
        iconId: 5,
        className: "el-icon-zoom-in",
        color: "#000",
        bg: "#edffec",
        content: "看透华而不实",
        useNum: 3,
        defaUseNum: 3,
        effect: "可不被遮挡的点击一张卡片",
      },
      // 6 下载
      6: {
        iconId: 6,
        className: "el-icon-download",
        color: "#000",
        bg: "#edfff7",
        content: "收藏, 留存, 记录, 分享",
        useNum: 3,
        defaUseNum: 3,
        effect: "清除卡槽中点击的卡片",
      },
      // 7 照相机
      7: {
        iconId: 7,
        className: "el-icon-camera",
        color: "#000",
        bg: "#ecfffe",
        content: "记录美好瞬间",
        useNum: 3,
        defaUseNum: 3,
        effect: "增加一张卡槽中点击的卡片",
      },
      // 8 录像机
      8: {
        iconId: 8,
        className: "el-icon-video-camera",
        color: "#000",
        bg: "#edfbff",
        content: "放映人生百态",
        useNum: 2,
        defaUseNum: 2,
        effect: "将卡槽的所有卡片重新放回游戏区",
        // effect: "复制顶层所有卡片",
      },
      // case 8: // 录像机
      //   if (
      //     !this.infoStore.isBanCardClick &&
      //     this.cardStore.cardData[8].useNum &&
      //     this.infoStore.isStarted &&
      //     this.cardStore.myCards.find((item) => item === 8)
      //   ) {
      //     this.startCode(8);
      //     const cards = this.infoStore.gameCards;
      //     const resultArr = []; // 可点击的卡片组 [存入gameCards索引]
      //     // 找到全部可点击[顶部]的卡片
      //     cards.forEach((item, i) => {
      //       if (this.isCardClick(item)) {
      //         resultArr.push(i);
      //       }
      //     });
      //     let oldCoor = { x: -1, y: -1 };
      //     resultArr.forEach((item) => {
      //       const card = cards[item];
      //       const coor = {
      //         x: getRandom(0, this.infoStore.size.w - 1, [oldCoor.x]),
      //         y: getRandom(0, this.infoStore.size.h - 1, [oldCoor.y]),
      //       };
      //       // 将卡片加入游戏中
      //       this.$store.commit("info/addGameCard", {
      //         cardId: this.infoStore.cardId,
      //         iconId: card.iconId,
      //         coor,
      //       });
      //       this.$store.commit("info/setCardId", this.infoStore.cardId + 1); // id+1
      //       oldCoor = coor;
      //     });
      //     console.log("成功复制顶层所有卡片");
      //   }
      //   break;

      // 9 铃铛
      9: {
        iconId: 9,
        className: "el-icon-bell",
        color: "#000",
        bg: "#edf5ff",
        content: "你这个年龄段, 你怎么睡得着觉？",
        useNum: 3,
        defaUseNum: 3,
        effect: "将最底层的3张卡片置于顶部",
      },
      // case 9: // 铃铛
      //   if (
      //     !this.infoStore.isBanCardClick &&
      //     this.cardStore.cardData[9].useNum &&
      //     this.infoStore.isStarted &&
      //     this.cardStore.myCards.find((item) => item === 9)
      //   ) {
      //     this.startCode(9);
      //     const cards = this.infoStore.gameCards;
      //     const curCard = cards[0]; // 记录第0张卡片
      //     this.$store.commit("info/deleteGameCard", 0); // 删除第0张卡片
      //     this.$store.commit("info/addGameCard", {
      //       cardId: this.infoStore.cardId,
      //       iconId: curCard.iconId,
      //       coor: {
      //         x: curCard.coor.x,
      //         y: curCard.coor.y,
      //       },
      //     }); // 将第0张卡片重新加入
      //     this.$store.commit("info/setCardId", this.infoStore.cardId + 1);
      //     console.log("成功将最底层卡片置于顶层");
      //   }
      //   break;

      // 10 加载
      10: {
        iconId: 10,
        className: "el-icon-refresh",
        color: "#000",
        bg: "#eef2ff",
        content: "等待的时间总是漫长的",
        useNum: 1,
        defaUseNum: 1,
        effect: "重新排列所有卡片",
      },
      // 11 文本
      11: {
        iconId: 11,
        className: "el-icon-tickets",
        color: "#000",
        bg: "#f3ecff",
        content: "今天做了些什么呢？",
        useNum: 1,
        defaUseNum: 1,
        effect: "右上角显示剩余卡片数[再次点击可关闭]",
      },
      // 12 电脑
      12: {
        iconId: 12,
        className: "el-icon-monitor",
        color: "#000",
        bg: "#fdefff",
        // content: "听说有人的电脑可以触屏呢 [doge]",
        content: "电脑电脑, 费电又费脑",
        useNum: 1,
        defaUseNum: 1,
        effect: "消除顶层的所有卡片",
      },
      // 13 剪刀
      13: {
        iconId: 13,
        className: "el-icon-scissors",
        color: "#000",
        bg: "#ffecfb",
        content: "剪去繁杂, 留下闲静",
        useNum: 2,
        defaUseNum: 2,
        effect: "消除点击区域的所有卡片",
      },
      // 14 消息
      14: {
        iconId: 14,
        className: "el-icon-chat-line-round",
        color: "#000",
        bg: "#ffedf5",
        content: "你好！再见",
        useNum: 1,
        defaUseNum: 1,
        effect: "可跳过关卡模式中前4关中的任意一关",
      },
      // 15 下雨
      15: {
        iconId: 15,
        className: "el-icon-heavy-rain",
        color: "#000",
        bg: "#ececec",
        content: "今天的天气又是雨呢",
        useNum: 2,
        defaUseNum: 2,
        effect: "将卡槽的所有卡片变成'雨'的卡片",
      },
      // 16 双向
      16: {
        iconId: 16,
        className: "el-icon-sort",
        color: "#000",
        bg: "#fff",
        content: "1+1可以大于2",
        useNum: 3,
        defaUseNum: 3,
        effect: "消除卡槽中数量为2的所有卡片",
      },
      // 17 樱桃
      17: {
        iconId: 17,
        className: "el-icon-cherry",
        color: "#000",
        bg: "#ffeff4",
        content: "樱花树和我好像并不相干",
        useNum: 1,
        defaUseNum: 1,
        effect: "消除所有'樱桃'卡片",
      },
      length: 18,
    },
    // 已拥有的卡片 [里面记录的是索引]
    // 获取全部卡片的加密字符串: srazbacbdcedfegfhgihjikjlkmlnmonpoqprq
    myCards: [],
    // 测试
    // myCards: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
    // 未获得的卡片
    notCards: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
    // 未获得的卡片的默认值
    notCardsDefa: [
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
    ],
    // 测试
    // notCards: [],
    // 加密
    encryption: {
      0: "az",
      1: "ba",
      2: "cb",
      3: "dc",
      4: "ed",
      5: "fe",
      6: "gf",
      7: "hg",
      8: "ih",
      9: "ji",
      10: "kj",
      11: "lk",
      12: "ml",
      13: "nm",
      14: "on",
      15: "po",
      16: "qp",
      17: "rq",
      18: "sr",
      19: "ts",
      20: "ut",
      21: "vu",
      22: "wv",
      23: "xw",
      24: "yx",
      25: "zy",
    },
    // 解密
    decryption: {
      az: 0,
      ba: 1,
      cb: 2,
      dc: 3,
      ed: 4,
      fe: 5,
      gf: 6,
      hg: 7,
      ih: 8,
      ji: 9,
      kj: 10,
      lk: 11,
      ml: 12,
      nm: 13,
      on: 14,
      po: 15,
      qp: 16,
      rq: 17,
      sr: 18,
      ts: 19,
      ut: 20,
      vu: 21,
      wv: 22,
      xw: 23,
      yx: 24,
      zy: 25,
    },
  },
  mutations: {
    // 设置是否显示剩余卡片数
    setIsShowCurCard(state, payload) {
      state.isShowCurCard = payload;
    },
    // 设置是否修改卡片
    setIsEdit(state, payload) {
      state.isEdit = payload;
    },
    // 设置是否消除卡片
    setIsDelete(state, payload) {
      state.isDelete = payload;
    },
    // 设置要修改的卡片的对象在gameCards中的索引 以及卡片信息 {i, cardId: card.cardId}
    setEditCard(state, payload) {
      state.editCard = payload;
    },
    // 设置是否考虑遮挡
    setIsCover(state, payload) {
      state.isCover = payload;
    },
    // 设置是否消除卡槽中点击的卡片
    setIsSlotDelete(state, payload) {
      state.isSlotDelete = payload;
    },
    // 设置是否增加卡槽中点击的卡片
    setIsSlotAdd(state, payload) {
      state.isSlotAdd = payload;
    },
    // 设置是否消除点击区域的所有卡片
    setIsDeleteArea(state, payload) {
      state.isDeleteArea = payload;
    },
    // 设置是否跳过关卡模式前4关中任意一关
    setIsPass(state, payload) {
      state.isPass = payload;
    },
    // 设置当前关卡时间数据是否有效
    setIsCanRanking(state, payload) {
      state.isCanRanking = payload;
    },
    // 设置卡片的使用次数
    setCardUseNum(state, payload) {
      // payload: {i: xxx, useNum: xxx}
      state.cardData[payload.i].useNum = payload.useNum;
    },
    // 重置所有卡片的使用次数 以及 将各变量重置为初始状态
    resetUseNum(state) {
      for (let i = 0; i < state.cardData.length; i++) {
        state.cardData[i].useNum = state.cardData[i].defaUseNum; // 设为默认值
      }
      state.isEdit = false; // 卡片不可修改 ['铅笔']
      state.isDelete = false; // 是否删除卡片 ['购物袋']
      state.isCover = true; // 考虑卡片遮挡 ['放大镜']
      state.isSlotDelete = false; // 是否删除卡槽卡片 ['下载']
      state.isSlotAdd = false; // 是否增加卡槽卡片 ['照相机']
      state.isDeleteArea = false; // 是否删除点击区域卡片 ['剪刀']
      state.isCanRanking = true; // 关卡数据是否有效
      // state.isPass = true; // 是否跳过关卡 ['消息']
      console.log("已重置卡片使用次数和卡片变量状态");
    },
    // 设置关卡进度
    setLevelNum(state, payload) {
      state.levelNum = payload;
    },
    // 设置当前关卡的时间
    setLevelTime(state, payload) {
      state.levelTime = payload;
    },
    // 设置当前关卡的计时器的id
    setLevelTimerId(state, payload) {
      state.levelTimerId = payload;
    },
    // 设置是否显示cmd窗口
    setIsShowCmd(state, payload) {
      state.isShowCmd = payload;
    },
    // 将进入游戏时候的时间戳存入本地
    putTime() {
      const timeStamp = Date.now();
      localStorage.setItem("curTime", timeStamp);
    },
    // 根据本地得到的上次登录的日期来刷新关卡进度
    updateLevel(state) {
      const timeStamp = localStorage.getItem("curTime"); // 从本地获取上次登录时间
      if (!timeStamp) {
        return;
      }
      const timeDate = new Date(+timeStamp); // 上次登录的日期对象
      const curDate = new Date(); // 当前时间的日期对象
      // console.log(timeDate.getDate(), curDate.getDate());
      if (
        timeDate.getDate() !== curDate.getDate() ||
        timeDate.getMonth() !== curDate.getMonth()
      ) {
        // 如果日期改变
        console.log("日期改变, 刷新关卡进度");
        state.levelNum = 1;
        this.commit("cards/putLevel"); // 加密并存入本地
      }
    },
    // 增加一张卡片至仓库
    addMycards(state, payload) {
      state.myCards.push(payload);
      for (let i = 0; i < state.notCards.length; i++) {
        if (payload === state.notCards[i]) {
          state.notCards.splice(i, 1); // 删除
        }
      }
      // 去重
      state.myCards = distinct(state.myCards);
      state.notCards = distinct(state.notCards);
    },
    // 解密本地的卡片至仓库
    getCards(state) {
      let isPwd = true; // 是否是正确格式的密码 [如果不是说明数据被修改]
      // 从本地获取包含自己所拥有卡片的卡片索引的最终加密字符串
      const cardsPwd = localStorage.getItem("myCards");
      if (!cardsPwd) {
        state.myCards = [];
        state.notCardsDefa.forEach((item) => {
          state.notCards.push(item);
        });
        console.log("我的卡片数:", 0);
        return;
      }
      const myCardNum = state.decryption[cardsPwd.slice(0, 2)]; // 自己的卡片数
      let notCardsPwd; // 随机的卡片的pwd
      let myCardsPwd; // 自己的卡片的pwd
      if (myCardNum === 0) {
        console.log("我的卡片数:", 0);
        return;
      }
      if (typeof myCardNum !== "number" && myCardNum > state.cardData.length) {
        isPwd = false;
      }
      console.log("我的卡片数:", myCardNum ? myCardNum : 0);
      if (isPwd) {
        notCardsPwd = cardsPwd.substring(
          2,
          2 * (state.cardData.length - myCardNum) + 2
        );
        // console.log("随机的卡片pwd -->", notCardsPwd);
        for (let i = 0; i < notCardsPwd.length; i += 2) {
          const item = state.decryption[notCardsPwd.substring(i, i + 2)];
          // console.log(typeof item, item);
          if (typeof item !== "number") {
            // 截取的部分不符合密码格式
            isPwd = false;
            break;
          }
        }
      }
      const getCards = []; // 解密出的卡片
      if (isPwd) {
        myCardsPwd = cardsPwd.substring(
          cardsPwd.length - 2 * myCardNum,
          cardsPwd.length
        );
        // console.log(">>>>>>>>>>>>>>");
        for (let i = 0; i < myCardsPwd.length; i += 2) {
          const item = state.decryption[myCardsPwd.substring(i, i + 2)]; // 截取的部分是否是密码
          // console.log(typeof item, i, item);
          if (typeof item !== "number" || item > state.cardData.length - 1) {
            isPwd = false;
            break;
          }
          getCards.push(item);
        }
        // console.log("我的卡片pwd -->", myCardsPwd);
      }
      if (!isPwd) {
        console.log("请不要随意修改本地数据哦");
        state.myCards = []; // 清空自己的卡片
        localStorage.setItem("myCards", ""); // 重置本地存储的卡片pwd
        return;
      }
      // console.log("我的卡片", getCards);
      // 存入仓库
      getCards.forEach((item) => {
        this.commit("cards/addMycards", item);
      });
    },
    // 加密拥有的卡片并存入本地
    putCards(state) {
      // 每两位算一个有效字段
      // [my卡片数str + 随机的卡片Str * (max卡片数 - my卡片数) + my卡片str * my卡片数]
      const myCards = distinct(state.myCards); // 去重
      if (myCards.length === 0) {
        // 自己没有卡片
        localStorage.setItem("myCards", "");
        return;
      }
      let putCards = state.encryption[myCards.length]; // 自己拥有的卡片的索引的加密字符串
      const notCardNum = state.cardData.length - myCards.length; // 自己可能没有的卡片 [随机]
      // console.log("初始编码:", putCards);
      for (let i = 0; i < notCardNum; i++) {
        putCards += state.encryption[getRandom(0, 25)];
      }
      // console.log("基础加密:", putCards);
      let myCardsPwd = "";
      for (let i = 0; i < myCards.length; i++) {
        myCardsPwd += state.encryption[myCards[i]];
      }
      putCards += myCardsPwd.substring(2, myCardsPwd.length);
      putCards += myCardsPwd.substring(0, 2);
      // console.log("最终加密:", putCards);
      localStorage.setItem("myCards", putCards); // 将加密的卡片存入本地
    },
    // 解密本地的关卡数据
    getLevel(state) {
      let isPwd = true;
      const myLevelPwd = localStorage.getItem("myLevel");
      if (!myLevelPwd) {
        console.log("当前关卡进度:", 1);
        return;
      }
      for (let i = 0; i < 8; i++) {
        const item = state.decryption[myLevelPwd.substring(2 * i, 2 * i + 2)];
        // console.log(typeof item, item);
        if (typeof item !== "number") {
          // 截取的部分不符合密码格式
          isPwd = false;
          break;
        }
      }
      const levelNum = state.decryption[myLevelPwd.substring(14, 16)]; // 读取关卡信息
      if (!isPwd || levelNum > levelData.length) {
        console.log("请不要随意修改本地数据哦");
        state.levelNum = 1; // 重置关卡进度为1
        localStorage.setItem("myLevel", "");
        return;
      }
      console.log("当前关卡进度:", levelNum);
      state.levelNum = levelNum;
    },
    // 加密当前关卡进度, 并存入本地
    putLevel(state) {
      // 每两位算一个有效字段
      // [随机加密串str * 7 + 当前关卡str]
      let levelPwd = "";
      for (let i = 0; i < 7; i++) {
        levelPwd += state.encryption[getRandom(0, 25)];
      }
      levelPwd += state.encryption[state.levelNum];
      // console.log(levelPwd);
      localStorage.setItem("myLevel", levelPwd); // 存入本地
    },
    // 清除本地记录
    clearCards() {
      localStorage.setItem("myCards", "");
      localStorage.setItem("myLevel", "");
    },
  },
};
